package com.qiaofang.common.interceptor;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.security.auth.message.AuthException;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class ControllerInterceptor {

    @Pointcut("execution(public * com..controller..*(..))")
    public void controllerMethodPointcut() {
    }


    @Around(value = "controllerMethodPointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = getRequest();
        log.info("请求地址:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("请求IP:" + request.getRemoteAddr());
        log.info("请求的类:" + point.getSignature().getDeclaringType());
        log.info("请求的方法:" + point.getSignature().getName());
        try {
            log.info("请求的参数：" + JSON.toJSONString(point.getArgs()));
        } catch (Exception e) {
        }

        long startTime = System.currentTimeMillis();
        try {
            Object response = point.proceed();
            // 2.打印出参，返回结果
            long endTime = System.currentTimeMillis();
            // 3.出参打印
            log.info("RESPONSE:{}", response != null ? JSON.toJSONString(response) : "");
            log.info("SPEND TIME : {}ms", (endTime - startTime));
            return response;
        } catch (AuthException e) {
            log.info("RESPONSE ERROR:{}", e.getMessage());
            throw e;
        } catch (MethodArgumentNotValidException e) {
            log.info("RESPONSE ERROR:{}", e.getMessage());
            throw e;
        } catch (Throwable e) {
            log.error("RESPONSE ERROR:{}", Arrays.toString(e.getStackTrace()));
            throw e;
        } finally {
            long endTime = System.currentTimeMillis();
            log.info("SPEND TIME : {}ms", (endTime - startTime));
        }
    }

    protected HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getRequest();
    }

}
